
interface IIterator {
    first();
    next();
    hasNext():boolean;
    isDone():boolean;
    currentItem():any;
}

interface IAggregate {
    createIterator():IIterator;
}

class ListIterator implements IIterator{
    constructor(private list:ListAggregate){
    }
    private index = 0;
    first(){
        this.index = 0;
    }
    next(){
        this.index++;
    }
    hasNext():boolean{
        return this.index < this.list.getSize()-1;
    }
    isDone():boolean{
        return this.index === this.list.getSize();
    }
    currentItem():any{
        if (this.index < this.list.getSize()){
            return this.list.getItemByIndex(this.index);
        }
        return null;
    }

}

class ListAggregate implements IAggregate{

    private list:number[] = [];

    createIterator():IIterator{
        return new ListIterator(this);
    }

    public getSize():number{
        return this.list.length;
    }

    public getItemByIndex(index:number):number{
        return this.list[index];
    }

    public addItem(item:number){
        this.list.push(item);
    }

}

function main() {
    const aggregate = new ListAggregate();
    aggregate.addItem(2);
    aggregate.addItem(2);
    aggregate.addItem(3);
    aggregate.addItem(4);

    const it:IIterator = aggregate.createIterator();
    while (!it.isDone()){
        log(it.currentItem())
        it.next();
    }
}
main();